#ifndef SK_GAME_ITEM_H
#define SK_GAME_ITEM_H

#include <QHash>
#include <QVector>

#include <QStyleOption>

class QPainter;
class QString;
class QGraphicsItem;
class QAbstractItemModel;

namespace sk
{
    class GameItemProperty;

	enum GameItemOperation
	{
		OP_RESET_SCENE_ITEM,
		NumGameItemOperations
	};	

    enum GameItemType
    {
        IT_Root,
        IT_Project,
        IT_Level,
        IT_Proxy,
        IT_Shape,
        IT_CircleShape,
        IT_BoxShape,
        IT_TriangleShape,
        NumItemTypes
    };

    class GameItem
    {
        friend class GameItemProxy;
    public:
        GameItem(GameItem * parent, int ind = 0);
        virtual ~GameItem();               
        virtual int numChilds();
        virtual int numChildsForProxy(int proxyInd);
        virtual void doDeleteChildForProxy(int proxyInd, int childInd);
        virtual GameItemType type() = 0;
        QVector<int> getIndex();
        GameItem * child(int i);
        GameItem * parent();
        virtual QGraphicsItem * createSceneItem();
        virtual GameItem * createItem(void * params);
        int index() const;
		void setIndex(int ind);
        bool validIndexesForSwap(int i, int j);
        virtual void * get(GameItemType type);
		void * getUpward(GameItemType type);
		void performForChilds(GameItemOperation op);
		// operations that every GameItem support
		bool perform(GameItemOperation op);
		// custom operations
		virtual bool performSpecial(GameItemOperation op);
		void resetSceneItem();

        virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, int row, int column);
        virtual QSize sizeHint(const QStyleOptionViewItem & option, int row, int column);

        void fillBg(QPainter * painter, const QStyleOptionViewItem & option, int row, int column);
        void paintText(QPainter * painter, const QStyleOptionViewItem & option, QString * text, int row, int column);        
        virtual int numProperties();
        virtual GameItemProperty * getProperty(int ind);
        virtual void onPropertyChange(GameItemProperty * property);

        virtual void onDoubleClickInProjectExplorer();
        virtual bool canDeleteFromProjectExplorer();
        virtual void doDelete();
        virtual void doDeleteChild(int ind);                       

        bool canSwapChilds() const;
        void setCanSwapChilds(bool canSwap);
        bool swapChilds(int i, int j);
        virtual void doSwapChilds(int i, int j);
        virtual void doSwapChildsForProxy(int proxyInd, int i, int j);

        bool canCloneChilds() const;
        void setCanCloneChilds(bool canClone);
        GameItem * cloneChild(int ind);
        virtual  void doCloneChild(int ind);
        virtual void doCloneChildForProxy(int proxyInd, int ind);

    protected:
        virtual GameItem * getChildItem(int i);                
        // never must be public!!!
        // call child(proxyInd)->child(childInd) instead if you need to get corresponding GameItem *
        virtual GameItem * getChildItemForProxy(int proxyInd, int childInd);

        GameItem * _parent;
        GameItem * _ci, *_cj;
        int _ind;
        bool _canSwapChilds, _canCloneChilds;
    public:
        QGraphicsItem * _sceneItem;
    protected:
        QHash<int, GameItem *> _childItems;
    };

} // namespace sk
#endif // SK_GAME_ITEM_H
